package cn.com.dhcc.ddi.datamapping.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.http.HttpSession;

import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.com.dhcc.app.core.base.BaseController;
import cn.com.dhcc.app.core.exception.DaoException;
import cn.com.dhcc.app.core.exception.ServiceException;
import cn.com.dhcc.app.core.handler.dbhandler.SingleTransationCircleWithOutResult;
import cn.com.dhcc.app.core.handler.modulehandler.WhereCondition;
import cn.com.dhcc.app.core.handler.pagerhandler.Pager;
import cn.com.dhcc.app.core.handler.pagerhandler.PagerData;
import cn.com.dhcc.app.core.pubmodule.sysmgr.usermgr.service.CmUserMgrService;
import cn.com.dhcc.app.core.pubmodule.sysmgr.usermgr.vo.UserInfoVo;
import cn.com.dhcc.app.core.service.BaseService;
import cn.com.dhcc.app.core.util.JsonUtil;
import cn.com.dhcc.app.core.util.StrUtil;
import cn.com.dhcc.app.core.util.UUIDGenerator;
import cn.com.dhcc.app.pub.CM;
import cn.com.dhcc.app.pub.core.tag.staticcode.StaticCode.FX_ACT_ON_TYPE;
import cn.com.dhcc.app.pub.core.tag.staticcode.StaticCode.FX_TYPE;
import cn.com.dhcc.ddi.datamapping.dao.DataMappingDao;
import cn.com.dhcc.ddi.datamapping.dao.FuncIdentifyDao;
import cn.com.dhcc.ddi.datamapping.dao.FuncMappingDao;
import cn.com.dhcc.ddi.datamapping.vo.DataMapping;
import cn.com.dhcc.ddi.datamapping.vo.FuncIdentify;
import cn.com.dhcc.ddi.datamapping.vo.FuncMapping;
import cn.com.dhcc.ddi.datasource.service.DataSourceDBService;
import cn.com.dhcc.ddi.datasource.service.DataSourceService;
import cn.com.dhcc.ddi.datasource.service.TableColService;
import cn.com.dhcc.ddi.datasource.service.TableInfoService;
import cn.com.dhcc.ddi.datasource.vo.DataSourceVo;
import cn.com.dhcc.ddi.datasource.vo.TableColVo;
import cn.com.dhcc.ddi.datasource.vo.TableInfoVo;
import cn.com.dhcc.ddi.task.service.transform.FuncHandlerInterface;
import cn.com.dhcc.ddi.task.service.transform.FunctionAction;

/**
 * 数据映射服务类
 *
 * @日期：2016/11/17 16:33:32
 * @作者：李博宇
 * @版权所有：东华软件
 * @版本：1.0
 */
@Service
public class DataMappingService extends BaseService {
	private Map<String,List<FuncMapping>> funcMap;
    @Autowired
    private DataMappingDao dataMappingDao;
    @Autowired
    private FuncMappingDao funcMappingDao;

    @Autowired
    private FuncIdentifyDao funcDao;
    @Autowired
    private DataSourceDBService dataSourceDBService;
	@Autowired
	FuncIdentityService funcIdentityService;
	@Autowired
	TableInfoService tableInfoService;
	@Autowired
	TableColService tableColService;
	@Autowired
	CmUserMgrService userMgrService;
	@Autowired
	DataSourceService dataSourceService;

	 public DataMapping get(String id) throws ServiceException {
		 try {
             return dataMappingDao.get(id);
         } catch (DaoException e) {
             throw new ServiceException("获取数据映射对象失败", e);
         }
	 }
	
    /**
     * 获取全部映射列表(有效列表)
     *
     * @return 全部映射列表
     * @throws ServiceException
     */
    public List<DataMapping> getMappingList() throws ServiceException {
        try {
            return dataMappingDao.getMappingList();
        } catch (DaoException e) {
            throw new ServiceException("获取全部数据映射列表失败", e);
        }
    }

    /**
     * @param @param  pager
     * @param @param  searchParameter
     * @param @return
     * @param @throws ServiceException 参数
     * @return PagerData<DataMapping> 返回类型
     * @throws
     * @Title: getPagerList
     * @Description: 获取数据映射列表
     */
    public PagerData<DataMapping> getPagerList(Pager pager, WhereCondition searchParameter) throws ServiceException {
        try {
            return dataMappingDao.getPagerList(pager, searchParameter);
        } catch (DaoException e) {
            throw new ServiceException("获取数据映射列表失败", e);
        }
    }
    
	/**
	 * 
	 * @Title: update
	 * @Description: 更新数据映射
	 * @param @param obj
	 * @param @return
	 * @param @throws ServiceException 参数
	 * @return int 返回类型
	 * @throws
	 */
    public int update(DataMapping obj) throws ServiceException {
        try {
            return dataMappingDao.update(obj);
        } catch (DaoException e) {
            throw new ServiceException("更新数据映射", e);
        }
    }

    /**
     * 根据id获取数据映射
     *
     * @param id 数据映射id
     * @return 数据映射
     * @throws ServiceException
     */
    public DataMapping getMappingById(String id) throws ServiceException {
        try {
            return dataMappingDao.getMappingById(id);
        } catch (DaoException e) {
            throw new ServiceException("获取数据映射失败", e);
        }
    }

    /**
     * @param @param  srcDsId
     * @param @return
     * @param @throws ServiceException 参数
     * @return int 返回类型
     * @throws
     * @Title: getCountBySrcDsId
     * @Description: 根据源端数据源id获取映射信息量
     */
    public int getCountBySrcDsId(String srcDsId) throws ServiceException {
        try {
            return dataMappingDao.getCountBySrcDsId(srcDsId);
        } catch (DaoException e) {
            throw new ServiceException("根据源端数据源id获取映射信息量失败", e);
        }
    }
    
    /**
     * 
     * @Title: getCountByDsId
     * @Description: 根据数据源id获取映射信息量
     * @param @param srcDsId
     * @param @return
     * @param @throws DaoException 参数
     * @return int 返回类型
     * @throws
     */
    public int getCountByDsId(String dsId) throws ServiceException {
        try {
            return dataMappingDao.getCountByDsId(dsId);
        } catch (DaoException e) {
            throw new ServiceException("根据数据源id获取映射信息量失败", e);
        }
    }

    /**
     * @param @param  vo
     * @param @param  funcMappingList
     * @param @throws ServiceException 参数
     * @return void 返回类型
     * @throws
     * @Title: batchInsert
     * @Description: 数据源映射信息入库
     */
    public void batchInsert(final DataMapping vo, final String funcMappingList) throws ServiceException {
        try {
            CM.getDao().doInSingleTransationCircle("数据源映射信息入库", new SingleTransationCircleWithOutResult() {
                @Override
                public void actionInCircle() throws RuntimeException {
                    try {
                        dataMappingDao.insert(vo);
                        funcMappingDao.batchInsert(getfuncMappingArray(funcMappingList));
                    } catch (Exception e) {
                        throw new RuntimeException("数据源映射信息入库失败", e);
                    }
                }
            });
        } catch (DaoException e) {
            throw new ServiceException("数据源映射信息入库失败", e);
        }
    }
    
	/**
	 * 
	 * @Title: update
	 * @Description: 更新数据源映射信息
	 * @param @param vo
	 * @param @param funcMappingList
	 * @param @throws ServiceException 参数
	 * @return void 返回类型
	 * @throws
	 */
    public void update(final DataMapping vo, final String funcMappingList) throws ServiceException {
        try {
            CM.getDao().doInSingleTransationCircle("更新数据源映射信息", new SingleTransationCircleWithOutResult() {
                @Override
                public void actionInCircle() throws RuntimeException {
                    try {
                        dataMappingDao.update(vo);
            			List<String> funcMappingIds = funcMappingDao.getIdsByMappingId(vo.getId());
            			for (String funcmId:funcMappingIds) {
            				funcMappingDao.delete(funcmId);
            			}
                        List<FuncMapping> list = getfuncMappingList(funcMappingList);
                        int fxExecOrder = 1;
                        for (FuncMapping funcMapping:list) {
                        	funcMapping.setFxExecOrder(fxExecOrder);
                    		funcMappingDao.insert(funcMapping);
                    		fxExecOrder += 1;
                        }
                    } catch (Exception e) {
                        throw new RuntimeException("更新数据源映射信息失败", e);
                    }
                }
            });
        } catch (DaoException e) {
            throw new ServiceException("更新数据源映射信息失败", e);
        }
    }

    /**
     * @param @param  id
     * @param @return
     * @param @throws ServiceException 参数
     * @return int 返回类型
     * @throws
     * @Title: delete
     * @Description: 删除数据映射
     */
    public int delete(String id) throws ServiceException {
        try {
            return dataMappingDao.delete(id);
        } catch (DaoException e) {
            throw new ServiceException("删除数据映射失败", e);
        }
    }

    /**
     * json字符串转换为List<Object[]>
     */
    public List<Object[]> getfuncMappingArray(String funcMappingList) {
    	funcMap = new LinkedHashMap<String, List<FuncMapping>>();
        List<Object[]> list = new ArrayList<Object[]>();
        JSONArray funcArray = new JSONArray(funcMappingList);
        for (int i = 0; i < funcArray.length(); i++) {
        	List<FuncMapping> funList = new ArrayList<FuncMapping>();
        	FuncMapping funcMapping = new FuncMapping();
            String funcInfo = (String) funcArray.get(i);
            Map<String, String> map = new LinkedHashMap<String, String>();
            map = JsonUtil.toMap(funcInfo);
            Object[] obj = new Object[9];
            obj[0] = (String) map.get("id");
            obj[1] = (String) map.get("mappingId");
            obj[2] = (String) map.get("tableName");
            obj[3] = (String) map.get("actObj");
            obj[4] = (String) map.get("fxId");
            obj[5] = JsonUtil.toJson(map.get("argContent"));
            obj[6] = (String) map.get("fxActOnType");
            obj[7] = i+1;//fxExecOrder
            obj[8] = new Date();
            list.add(obj);
            
            //设置funcMap
            funcMapping.setActObj((String) map.get("actObj"));
            funcMapping.setFxId((String) map.get("fxId"));
            funcMapping.setArgContent(JsonUtil.toJson(map.get("argContent")));
            funcMapping.setFxActOnType((String) map.get("fxActOnType"));
            String tableName = (String) map.get("tableName");
            funcMapping.setTableName(tableName);
            if(funcMap.get(tableName) != null){
          		funList = funcMap.get(tableName);
        	}

			funList.add(funcMapping);
			funcMap.put(tableName, funList);           	

        }
        return list;
    }
    
    /**
     * json字符串转换为List<FuncMapping>
     */
    public List<FuncMapping> getfuncMappingList(String funcMappingList) {
    	 List<FuncMapping> list = new ArrayList<FuncMapping>();
         JSONArray funcArray = new JSONArray(funcMappingList);
         for (int i = 0; i < funcArray.length(); i++) {
         	List<FuncMapping> funList = new ArrayList<FuncMapping>();
         	FuncMapping funcMapping = new FuncMapping();
            String funcInfo = (String) funcArray.get(i);
            Map<String, String> map = new LinkedHashMap<String, String>();
            map = JsonUtil.toMap(funcInfo);
            funcMapping.setId((String) map.get("id"));
            funcMapping.setMappingId((String) map.get("mappingId"));
            funcMapping.setTableName((String) map.get("tableName"));
            funcMapping.setActObj((String) map.get("actObj"));
            funcMapping.setFxId((String) map.get("fxId"));
            funcMapping.setArgContent(JsonUtil.toJson(map.get("argContent")));
            funcMapping.setFxActOnType((String) map.get("fxActOnType"));
            try {
				funcMapping.setFuncIdentify(funcIdentityService.getById((String) map.get("fxId")));
			} catch (ServiceException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
             funcMapping.setMtime(new Date());
          
             list.add(funcMapping);
         }
         return list;
    }

    /**
     * 调用函数
     * @param fxId 函数id
     * @param actObj 作用对象
     * @param argContent 参数
     * @return
     * @throws ServiceException
     */
    public String callFunc(String fxId, String actObj, String argContent) throws ServiceException {
        try {
            FuncIdentify func = funcDao.get(fxId);
            String fxName = func.getFxNameEn();
            List<String> args = new ArrayList<String>();
            if (StrUtil.isNotBank(actObj)) {
                args.add(actObj);
            }
            if (!argContent.isEmpty()) {
            	JSONArray argContentArray = new JSONArray(argContent);
            	for (int i = 0; i < argContentArray.length(); i++) {
            		String argCon = JSONObject.valueToString(argContentArray.get(i));
            		argCon = dataSourceDBService.relaceStr(argCon);
            		Map<String, String> argsMap = JsonUtil.toMap(argCon);
                    for (String key : argsMap.keySet()) {
                        args.add(argsMap.get(key));
                    }
            	}
            }
            FuncHandlerInterface handler = getFuncHandlerInterface(func);
            String val = (String) handler.call(fxName, args);
            return val;
        } catch (Exception e) {
            throw new ServiceException("调用函数失败", e);
        }
    }
    
	/**
	 * 
	 * @Title: callRemoveFunc
	 * @Description: 调用函数(移除表、移除字段)
	 * @param @param fxId
	 * @param @param tableName
	 * @param @param argContent
	 * @param @return
	 * @param @throws ServiceException 参数
	 * @return boolean 返回类型
	 * @throws
	 */
    public boolean callRemoveFunc(String fxId, String tableName, String argContent, String fxType) throws ServiceException {
        try {
            FuncIdentify func = funcDao.get(fxId);
            String fxName = func.getFxNameEn();
            List<String> args = new ArrayList<String>();
            args.add(tableName);
            String arg = "";
            if (!argContent.isEmpty()) {
            	arg = getArg(argContent,fxType,"0");
            	args.add(arg);
            }
            FuncHandlerInterface handler = getFuncHandlerInterface(func);
            boolean val = (Boolean) handler.call(fxName, args);
            return val;
        } catch (Exception e) {
            throw new ServiceException("调用函数失败", e);
        }
    }
    
	/**
	 * 
	 * @Title: getArg
	 * @Description: 获取参数
	 * @param @param argContent
	 * @param @param fxType
	 * @param @param ifGetArg    1 获取参数  0获取表名或列名
	 * @param @return 参数
	 * @return String 返回类型
	 * @throws
	 */
    public String getArg(String argContent, String fxType, String ifGetArg){
    	String arg = "";
    	if (!argContent.isEmpty()) {
    		JSONArray argContentArray = new JSONArray(argContent);
        	for (int i = 0; i < argContentArray.length(); i++) {
        		String argCon = JSONObject.valueToString(argContentArray.get(i));
        		argCon = dataSourceDBService.relaceStr(argCon);
        		Map<String, String> argsMap = JsonUtil.toMap(argCon);
        		if (("1").equals(ifGetArg)) {
                    if (i != 0) {
       		    	    if (i==1) {
       		    		    arg += JsonUtil.toJson(argsMap); 
       		    	    } else {
       		    		    arg += "," + JsonUtil.toJson(argsMap);
       		    	    }
       		        }
                    if (i == argContentArray.length() - 1) {
                    	arg = "["+ arg +"]";
                    }
        		} else {
                    for (String key : argsMap.keySet()) {
                    	arg += argsMap.get(key);
                    }
            		if (("3").equals(fxType) || ("5").equals(fxType)) {
            			break;
            		}
                    if (i < argContentArray.length()-1) {
                        arg += ",";
                    }
        		}
        	}
    	}
    	return arg;
    }  
    

    /**
     * 获取函数处理类
     *
     * @param func
     * @return
     */
    private FuncHandlerInterface getFuncHandlerInterface(FuncIdentify func) {
        return (FuncHandlerInterface) CM.getBean(FuncIdentify.FUNC_TYPE.find(func.getIsCustomized()).getHandler());
    }
    
	/**
	 * 
	 * @Title: getFuncMap
	 * @Description: 获取funcMap
	 * @param @return 参数
	 * @return Map<String,List<FuncMapping>> 返回类型
	 * @throws
	 */
    public Map<String,List<FuncMapping>> getFuncMap(){
    	return funcMap;
    }
    
	/**
	 * 
	 * @Title: realtimePreview
	 * @Description: 实时预览
	 * @param @param srcDsId
	 * @param @param funcMappingList
	 * @param @return
	 * @param @throws ServiceException 参数
	 * @return Map<String,Map<String,Object>> 返回类型
	 * @throws
	 */
    public Map<String,Map<String, Object>> realtimePreview(String srcDsId, List<FuncMapping> funcMList) throws ServiceException{
        try {        	
        	 // Map<表名,{ifIsomorphism:1同构||0异构(String), originTable：值，mappingAfterTable:值}> 
        	 // 同构时mappingAfterTable为null，异构时如果是排除表则mappingAfterTable为null       	 
        	Map<String,Map<String,Object>> tableMappingMap = new TreeMap<String, Map<String,Object>>();       	 
        	//查询源端数据源表信息
    		Map<String, TableInfoVo> tabInfoMap = getDsInfoMap(srcDsId);
    		String isGetArg = "1";
    		String notGetArg = "0";
        	for (FuncMapping funcM:funcMList) {
        		String fxActOnType = funcM.getFxActOnType();
        		String tableName = funcM.getTableName();
        		String argContent = funcM.getArgContent();
        		String actObj = funcM.getActObj();       		
        		FuncIdentify funcIdentify = funcM.getFuncIdentify();
        		String fxType = funcIdentify.getFxType();        		
    			TableInfoVo mappingAfterTab = new TableInfoVo();
    			mappingAfterTab = getMapppingAfterTab(tableMappingMap,tabInfoMap, tableName, mappingAfterTab);   			
    			Map<String,TableColVo> mappingTabColMap = new LinkedHashMap<String, TableColVo>();
    			TableColVo mappingTabCol = new TableColVo();
    			if (!(FX_ACT_ON_TYPE.ACT_TABLE_NAME.getCode()).equals(fxActOnType)) {
    				if (mappingAfterTab != null) {
        				mappingTabColMap = mappingAfterTab.getTabColMap();//映射后列集合
        				if (mappingTabColMap != null) {
            				mappingTabCol = mappingTabColMap.get(actObj);//映射后列信息
        				}
    				}
    			}        	
        		if ((FX_ACT_ON_TYPE.ACT_TABLE_NAME.getCode()).equals(fxActOnType)) {//函数作用在表名上
        			if ((FX_TYPE.TABLE_BATCH_OPR.getCode()).equals(fxType)) {//表批量操作
        				tabBatchOpr(tableMappingMap, tabInfoMap, funcIdentify, funcM, notGetArg);
        			}
        			if ((FX_TYPE.TABLE_NAME_OPR.getCode()).equals(fxType)) {//表名操作
						tabNmOpr(tableMappingMap, tabInfoMap, mappingAfterTab, funcM, actObj, argContent);
        			}
        			if ((FX_TYPE.TABLE_NAME_BATCH_OPR.getCode()).equals(fxType)) {//表名批量操作
    					tabNmBatchOpr(tableMappingMap, tabInfoMap, mappingAfterTab, funcM, funcIdentify, isGetArg, notGetArg);
        			}
        		}
        		if ((FX_ACT_ON_TYPE.ACT_FIELD_NAME.getCode()).equals(fxActOnType)) {//函数作用在字段名上
        			
        			if ((FX_TYPE.FIELD_NAME_OPR.getCode()).equals(fxType)) {//字段名操作
        				colNmOpr(srcDsId, tableMappingMap, tabInfoMap, mappingTabColMap, mappingTabCol, mappingAfterTab, funcM, funcIdentify, argContent, actObj);
        			}
        			if ((FX_TYPE.FIELD_NAME_BATCH_OPR.getCode()).equals(fxType)) {//字段名批量操作
        				colNmBatchOpr(srcDsId, tableMappingMap, tabInfoMap, mappingTabColMap, mappingAfterTab, funcM, funcIdentify, notGetArg, isGetArg);
        			}
        		}
        		if ((FX_ACT_ON_TYPE.ACT_FIELD_VALUE.getCode()).equals(fxActOnType)) {//函数作用在字段值上
        			if ((FX_TYPE.FIELD_VALUE_OPR.getCode()).equals(fxType)) {//字段值操作
						colValOpr(tableMappingMap, tabInfoMap, mappingTabColMap, mappingTabCol, funcIdentify, mappingAfterTab, funcM);
        			}
        		}
        	}
        	for (String key:tabInfoMap.keySet()) {
        		Map<String,Object> mapTable =  tableMappingMap.get(key);
        		if (mapTable == null) {
        			setNotIsomerism(tableMappingMap, tabInfoMap, key);
        		}
        	}
    		return tableMappingMap;
		} catch (Exception e) {
			throw new ServiceException("实时预览失败", e);
		}
    }

	/**
	 * 
	 * @Title: colValOpr
	 * @Description: 字段值操作
	 * @param @throws ServiceException 参数
	 * @return void 返回类型
	 * @throws
	 */
	private void colValOpr(Map<String, Map<String, Object>> tableMappingMap, Map<String, TableInfoVo> tabInfoMap,
			Map<String, TableColVo> mappingTabColMap, TableColVo mappingTabCol, 
			FuncIdentify funcIdentify, TableInfoVo mappingAfterTab, FuncMapping funcM)
			throws ServiceException {
		String fxId = funcM.getFxId();
		String tableName = funcM.getTableName();
		String actObj = funcM.getActObj();
		String argContent = funcM.getArgContent();
		if (funcIdentify.getFxNameEn().equals(FunctionAction.SET_DEFAULT)
			|| funcIdentify.getFxNameEn().equals(FunctionAction.SET_CURRENTDATE)) {
			String mappingDefVal = callFunc(fxId, "", argContent);
			mappingTabCol.setColDefault(mappingDefVal);
			if (mappingTabColMap != null) {
				//mappingTabColMap.put(actObj, mappingTabCol);
				//mappingAfterTab.setTabColMap(mappingTabColMap);
				setIsomerism(tableMappingMap, tabInfoMap, tableName, mappingAfterTab);
			}
		}if(funcIdentify.getFxNameEn().equals(FunctionAction.STRING_TO_DATE)
			|| funcIdentify.getFxNameEn().equals(FunctionAction.CONVERT_TO_LONG)){
			setIsomerism(tableMappingMap, tabInfoMap, tableName, mappingAfterTab);
		}else{
			Map<String,Object> mapTable =  tableMappingMap.get(tableName);
			if(mapTable == null){
				setNotIsomerism(tableMappingMap, tabInfoMap, tableName);
			}
		}
	}
    
	/**
	 * 
	 * @Title: colNmBatchOpr
	 * @Description: 字段名批量操作
	 * @param @throws ServiceException 参数
	 * @return void 返回类型
	 * @throws
	 */
    private void colNmBatchOpr(String srcDsId, Map<String, Map<String, Object>> tableMappingMap, Map<String, TableInfoVo> tabInfoMap, 
    		Map<String, TableColVo> mappingTabColMap, TableInfoVo mappingAfterTab, FuncMapping funcM, FuncIdentify funcIdentify,
    		String notGetArg, String isGetArg) throws ServiceException{
    	String argContent = funcM.getArgContent();
    	String actObj = funcM.getActObj();
    	String tableName = funcM.getTableName();
    	String fxActOnType = funcM.getFxActOnType();
    	String fxType = funcIdentify.getFxType();
    	if (FunctionAction.REMOVE_COL.equals(funcIdentify.getFxNameEn())) {
			removeCol(tableMappingMap, tabInfoMap, mappingAfterTab, null, fxActOnType, actObj, argContent, mappingTabColMap, funcIdentify, isGetArg, notGetArg);
		} else {
			String arg[] = {};
			String cols = getArg(argContent,fxType,notGetArg);
			if (StrUtil.isNotBank(cols)) {
				arg = cols.split(",");
			}
			for (String col:arg) {				
				if (mappingTabColMap != null) {
					TableColVo mappingTabCol = mappingTabColMap.get(col);//映射后列信息
					if (mappingTabCol != null) {
	    				/*String mappingColName = callFunc(fxId, col, getArg(argContent,fxType,isGetArg));
	    				mappingTabCol.setColName(mappingColName);
	    				//mappingTabColMap.
	    				mappingAfterTab.setTabColMap(mappingTabColMap);
	    				setIsomerism(tableMappingMap, tabInfoMap, tableName, mappingAfterTab);*/
						String argCon = getArg(argContent,fxType,isGetArg);
	    				colNmOpr(srcDsId, tableMappingMap, tabInfoMap, mappingTabColMap, mappingTabCol, mappingAfterTab, funcM, funcIdentify, argCon, col);
					}
				}
			}
		}
    }

	/**
	 * 
	 * @Title: colNmOpr
	 * @Description: 字段名操作
	 * @param @throws ServiceException 参数
	 * @return void 返回类型
	 * @throws
	 */
	private void colNmOpr(String srcDsId, Map<String, Map<String, Object>> tableMappingMap, Map<String, TableInfoVo> tabInfoMap,
			Map<String, TableColVo> mappingTabColMap, TableColVo mappingTabCol, TableInfoVo mappingAfterTab,
			FuncMapping funcM, FuncIdentify funcIdentify, String argContent, String actObj)
			throws ServiceException {
		String fxId = funcM.getFxId();
		String tableName = funcM.getTableName();
		if(FunctionAction.ADD_COL.equals(funcIdentify.getFxNameEn())){
			mappingTabCol = new TableColVo();
			String argCon = dataSourceDBService.relaceStr(argContent);
			Map<String, String> argsMap = JsonUtil.toMap(argCon);
		    String vrType = argsMap.get("vrType");
			mappingTabCol.setColName(actObj);
			mappingTabCol.setColComment("(虚拟字段)");
			mappingTabCol.setDsId(srcDsId);
			mappingTabCol.setId(UUIDGenerator.getUUID());
			mappingTabCol.setTableId(mappingAfterTab.getId());
			mappingTabCol.setIsIc("0");
			mappingTabCol.setIsPk("0");
			mappingTabCol.setMtime(new Date());
			String vrFxId = argsMap.get("fxId");
			if (StrUtil.isNotBank(vrFxId)) {
				FuncIdentify funcIdentify2 = funcIdentityService.getById(vrFxId);
				if (vrType.equals("0") && !FunctionAction.WHEN_NULL_SET_DEFAULT.equals(funcIdentify2.getFxNameEn())) {
					String colDefault = callFunc(argsMap.get("fxId"), actObj, JSONObject.valueToString(argsMap.get("args")));
					mappingTabCol.setColDefault(colDefault);
				}
				mappingTabColMap.put(actObj, mappingTabCol);
				mappingAfterTab.setTabColMap(mappingTabColMap);
			}
		} else {
			if (mappingTabCol != null) {
				String mappingColName = callFunc(fxId, actObj, argContent);
				mappingTabCol.setColName(mappingColName);
			}
		}
		setIsomerism(tableMappingMap, tabInfoMap, tableName, mappingAfterTab);
	}

	/**
	 * 
	 * @Title: tabNmBatchOpr
	 * @Description: 表名批量操作
	 * @param @throws ServiceException 参数
	 * @return void 返回类型
	 * @throws
	 */
	private void tabNmBatchOpr(Map<String, Map<String, Object>> tableMappingMap, Map<String, TableInfoVo> tabInfoMap,
			TableInfoVo mappingAfterTab, FuncMapping funcM, FuncIdentify funcIdentify, String isGetArg, String notGetArg) throws ServiceException {
		String fxType = funcIdentify.getFxType();
		String argContent = funcM.getArgContent();
		String tabs[] = {};
		String tables = getArg(argContent, fxType, notGetArg);
		if (StrUtil.isNotBank(tables)) {
			tabs = tables.split(",");
		}
		String args = getArg(argContent, fxType, isGetArg);
		for (String tabName:tabs) {
			mappingAfterTab = getMapppingAfterTab(tableMappingMap, tabInfoMap, tabName, mappingAfterTab);
			tabNmOpr(tableMappingMap, tabInfoMap, mappingAfterTab, funcM, tabName, args);
		}
	}

	/**
	 * 
	 * @Title: tabNmOpr
	 * @Description: 表名操作
	 * @param @throws ServiceException 参数
	 * @return void 返回类型
	 * @throws
	 */
	private void tabNmOpr(Map<String, Map<String, Object>> tableMappingMap,
			Map<String, TableInfoVo> tabInfoMap,
			TableInfoVo mappingAfterTab, FuncMapping funcM, String actObj, String argContent) throws ServiceException {
		String fxId = funcM.getFxId();
		String mappingTabName = callFunc(fxId, actObj, argContent);
		mappingAfterTab.setTableName(mappingTabName);//设置映射后的表名       				
		setIsomerism(tableMappingMap, tabInfoMap, actObj, mappingAfterTab);
	}

	/**
	 * 
	 * @Title: tabBatchOpr
	 * @Description: 表批量操作
	 * @param @throws ServiceException 参数
	 * @return void 返回类型
	 * @throws
	 */
	private void tabBatchOpr(Map<String, Map<String, Object>> tableMappingMap, Map<String, TableInfoVo> tabInfoMap, FuncIdentify funcIdentify,
			FuncMapping funcM, String notGetArg) throws ServiceException {
		String fxType = funcIdentify.getFxType();
		String fxId = funcIdentify.getId();
		String argContent = funcM.getArgContent();
		if (FunctionAction.REMOVE_TABLE.equals(funcIdentify.getFxNameEn())) {
			boolean removeFlag = false;
			String arg[] = {};
			String tables = getArg(argContent, fxType, notGetArg);
			if (StrUtil.isNotBank(tables)) {
				arg = tables.split(",");
			}
			for (String tabName:arg) {
				Map<String, Object> map = new LinkedHashMap<String, Object>();
				removeFlag = callRemoveFunc(fxId, tabName, argContent, fxType);
				if (removeFlag) {
					map.put("ifIsomorphism", "0");
					map.put("originTable", tabInfoMap.get(tabName));
					tableMappingMap.put(tabName, map);
				}
			}
		}
	}

	/**
	 * 
	 * @Title: setNotIsomerism
	 * @Description: 设置同构
	 * @param @param tableMappingMap
	 * @param @param tabInfoMap
	 * @param @param map
	 * @param @param key 参数
	 * @return void 返回类型
	 * @throws
	 */
	private void setNotIsomerism(Map<String, Map<String, Object>> tableMappingMap, Map<String, TableInfoVo> tabInfoMap, String key) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("ifIsomorphism", "1");//同构
		map.put("originTable", tabInfoMap.get(key));
		tableMappingMap.put(key, map);
	}
    
	/**
	 * 
	 * @Title: setIsomerism
	 * @Description: 设置异构
	 * @param @param tableMappingMap
	 * @param @param tabInfoMap
	 * @param @param map
	 * @param @param tableName
	 * @param @param mappingAfterTab 参数
	 * @return void 返回类型
	 * @throws
	 */
	private void setIsomerism(Map<String, Map<String, Object>> tableMappingMap, Map<String, TableInfoVo> tabInfoMap,
              String tableName, TableInfoVo mappingAfterTab) {
		Map<String, Object> map = new LinkedHashMap<String, Object>();
		map.put("ifIsomorphism", "0");
		map.put("originTable", tabInfoMap.get(tableName));
		map.put("mappingAfterTable", mappingAfterTab);
		tableMappingMap.put(tableName, map);
	}

	/**
	 * 
	 * @Title: getMapppingAfterTab
	 * @Description: 获取映射后表信息
	 * @param @param tableMappingMap
	 * @param @param tabInfoMap
	 * @param @param tableName
	 * @param @param mappingAfterTab
	 * @param @return 参数
	 * @return TableInfoVo 返回类型
	 * @throws
	 */
	private TableInfoVo getMapppingAfterTab(Map<String, Map<String, Object>> tableMappingMap,
			Map<String, TableInfoVo> tabInfoMap, String tableName,
			TableInfoVo mappingAfterTab) {
		if (tableMappingMap.get(tableName)!= null) {
			mappingAfterTab = (TableInfoVo)tableMappingMap.get(tableName).get("mappingAfterTable");
		} else if(StrUtil.isNotBank(tableName)) {
			if (tabInfoMap.get(tableName) != null) {
				 mappingAfterTab = tabInfoMap.get(tableName).clone(tabInfoMap.get(tableName));//映射后表信息
			}
		}
		return mappingAfterTab;
	}

	/**
	 * 
	 * @Title: getDsInfoMap
	 * @Description: 组装数据源表信息
	 * @param @param srcDsId
	 * @param @return
	 * @param @throws ServiceException 参数
	 * @return Map<String,TableInfoVo> 返回类型
	 * @throws
	 */
	private Map<String, TableInfoVo> getDsInfoMap(String srcDsId) throws ServiceException {
		List<TableInfoVo> tableInfoList = tableInfoService.getTableInfoByDsId(srcDsId);
		for (int i = 0; i < tableInfoList.size(); i++) {
			String tableId = tableInfoList.get(i).getId();
			List<TableColVo> tableColList = tableColService.getColsByTableId(tableId);
			tableInfoList.get(i).setTableColVos(tableColList);
		}
		Map<String,TableInfoVo> tabInfoMap = tableInfoService.getTabInfoMap(tableInfoList);
		return tabInfoMap;
	}

	/**
	 * 排除字段
	 */
	private void removeCol(Map<String, Map<String, Object>> tableMappingMap, Map<String, TableInfoVo> tabInfoMap, TableInfoVo mappingAfterTab,
			FuncMapping funcMapInfo, String fxActOnType, String actObj,
			String argContent, Map<String, TableColVo> mappingTabColMap, FuncIdentify funcIdentify,
			String isGetArg, String notGetArg) {
		if (fxActOnType.equals("2") && FunctionAction.REMOVE_COL.equals(funcIdentify.getFxNameEn())) {
			String tabArr = getArg(argContent, funcIdentify.getFxType(), notGetArg );
			String colArr = getArg(argContent, funcIdentify.getFxType(), isGetArg);
			colArr = getArg(colArr, funcIdentify.getFxType(), notGetArg);
			if (StrUtil.isNotBank(tabArr)) {
				for (String tab: tabArr.split(",")) {
					mappingAfterTab = getMapppingAfterTab(tableMappingMap, tabInfoMap, tab, mappingAfterTab);
					mappingTabColMap = mappingAfterTab.getTabColMap();
					if (StrUtil.isNotBank(colArr)) {
						for (String col: colArr.split(",")) {
							if (mappingTabColMap != null) {
								TableColVo colVo = mappingTabColMap.get(col);//(mappingTabColMap.get(col)).clone(mappingTabColMap.get(col));
								if (colVo != null) {
									mappingTabColMap.remove(col);
									mappingAfterTab.setTabColMap(mappingTabColMap);
									setIsomerism(tableMappingMap, tabInfoMap, tab, mappingAfterTab);
								}
							}
						}
					}
				}
			}
		}
	}
    
	/**
	 * 
	 * @Title: setFuncMap
	 * @Description: 获取funcMap
	 * @param @param funcMap 参数
	 * @return void 返回类型
	 * @throws
	 */
    public void setFuncMap(Map<String, List<FuncMapping>> funcMap) {
		this.funcMap = funcMap;
	}
    
	/**
	 * 验证名称唯一性
	 * @param name
	 * @param checkStr
	 * @return
	 * @throws ServiceException
	 */
	public boolean isPropertyUnique(String propertyName, String newValue, String oldValue, HttpSession httpSession) throws ServiceException {
		try {
			if (newValue.equals(oldValue)) {
				return true;
			}
			WhereCondition searchParameter = new WhereCondition();
			searchParameter.where().eq(propertyName, newValue);
			
			Boolean isAdmin = BaseController.getCurrentUserInfo(httpSession).isSuperAdmin();
			String userId = BaseController.getCurrentUserInfo(httpSession).getId();
			UserInfoVo currentUser = userMgrService.getUserById(userId);
			if (!isAdmin) {
				if (currentUser != null) {
					String nodeIdsStr = currentUser.getExt2();
					if (StrUtil.isNotBank(nodeIdsStr)) {
						String[] nodeIds = nodeIdsStr.split(",");
						WhereCondition condition = new WhereCondition();
						condition.and().in("node_id", nodeIds);
						List<DataSourceVo> list = dataSourceService.getDsList(condition);
						String[] dsIds = new String[list.size()];
						for (int i=0; i < list.size(); i++) {
							dsIds[i] = list.get(i).getId();
						}
						searchParameter.andIn("src_ds_id", dsIds);
						searchParameter.andIn("dest_ds_id", dsIds);
					}else{
						searchParameter.andEq("1", "2");
					}
				}
			}
			return dataMappingDao.count(searchParameter) == 0;
		} catch (DaoException e) {
			throw new ServiceException(e);
		}
	}
    public List<String> getDmid(WhereCondition searchParameter) throws ServiceException {
        try {
            return dataMappingDao.getDmid(searchParameter);
        } catch (DaoException e) {
            throw new ServiceException(e);
        }
    }

    public List<DataMapping> getMappingList(WhereCondition searchParameter) throws ServiceException {
        try {
            return dataMappingDao.getMappingList(searchParameter);
        } catch (DaoException e) {
            throw new ServiceException(e);
        }
    }
}
